﻿using System;
using System.Collections.Generic;
using System.Data.Linq;

namespace BReusable
{
	public static class LinqLib
	{
		/// <summary>
		/// From BReusable
		/// </summary>
		/// <typeparam name="TDataContext"></typeparam>
		/// <param name="a"></param>
		/// <returns></returns>
		public static Action Using<TDataContext>(Action<TDataContext> a)
	where TDataContext : DataContext, new()
		{
			return () =>
			{
				using (var dc = new TDataContext())
				{
					a(dc);
				}

			};

		}
		/// <summary>
		/// reflects on the properties and their System.Data.Linq.Mapping.ColumnAttribute
		/// From BReusable
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public static List<String> GetColumnNames(Type type)
		{
			var result = new List<String>();
			System.Reflection.PropertyInfo[] prop = type.GetProperties();
			foreach (var item in prop)
			{
				var info = item.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), true);
				if (info.Length == 1)
				{
					result.Add(item.Name); // also ca.storage without the leading _ may work.
					//var ca = (System.Data.Linq.Mapping.ColumnAttribute)info[0];

				}
				else ("property had more than 1 column Attribute:" + item.Name).ToDebug();
			}
			return result;
		}

		/// <summary>
		/// Gets the length limit for a given field on a LINQ object ... or zero if not known
		/// From BReusable
		/// </summary>
		/// <remarks>
		/// You can use the results from this method to dynamically 
		/// set the allowed length of an INPUT on your web page to
		/// exactly the same length as the length of the database column.  
		/// Change the database and the UI changes just by
		/// updating your DBML and recompiling.
		/// </remarks>
		public static int GetLengthLimit(object obj, string field)
		{
			int dblenint = 0;   // default value = we can't determine the length

			Type type = obj.GetType();
			System.Reflection.PropertyInfo prop = type.GetProperty(field);
			// Find the Linq 'Column' attribute
			// e.g. [Column(Storage="_FileName", DbType="NChar(256) NOT NULL", CanBeNull=false)]
			object[] info = prop.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), true);
			// Assume there is just one
			if (info.Length == 1)
			{
				System.Data.Linq.Mapping.ColumnAttribute ca = (System.Data.Linq.Mapping.ColumnAttribute)info[0];

				string dbtype = ca.DbType;

				if (dbtype.StartsWith("Char(") || dbtype.StartsWith("VarChar("))
				{
					int index1 = dbtype.IndexOf("(");
					int index2 = dbtype.IndexOf(")");
					string dblen = dbtype.Substring(index1 + 1, index2 - index1 - 1);
					int.TryParse(dblen, out dblenint);
				}
			}
			return dblenint;
		}

	}
}
